/*
 * FSWUniCEUB - 2008
 * 
 * Este arquivo é de propriedade da Fábrica de Software do UniCEUB
 * 
 * Para mais informações entre em contato com a coordenação do
 * curso de Ciência da Computação da instituição.
 */
package br.uniceub.fsw.seguranca.dao;

import br.uniceub.fsw.arquitetura.persistencia.dao.BaseDAO;
import br.uniceub.fsw.arquitetura.persistencia.dao.ConstrutorSQL;
import br.uniceub.fsw.seguranca.vo.ModuloVO;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Data Access Object - Usuário
 * Camada de modulo ao banco de dados da entidade Usuário.
 * 
 * @author Bruno Schifer Bernardi
 */
public class ModuloDAO extends BaseDAO<ModuloVO> {

    @Override
    public void inserir(ModuloVO entidade) {
        ConstrutorSQL sql = new ConstrutorSQL();

        sql.append("INSERT INTO TB_MODULO(NO_MODULO, CD_MODULO, DS_MODULO, DS_CHAMADA, ST_ATIVO)");
        sql.append("VALUES (?,?,?,?,?)");

        List<?> parametros = criarParametros(entidade.getNoModulo(),
                entidade.getCdModulo(), entidade.getDsModulo(), entidade.getDsChamada(),
                entidade.getStAtivo());
        
        Integer idGerado = ((Long) executarInsercao(sql.toString(), parametros)).intValue();

        entidade.setIdModulo(idGerado);
    }

    @Override
    public void alterar(ModuloVO entidade) {
        ConstrutorSQL sql = new ConstrutorSQL();

        sql.append("UPDATE TB_MODULO SET NO_MODULO = ?,");
        sql.append("CD_MODULO = ?,");
        sql.append("DS_MODULO = ?,");
        sql.append("DS_CHAMADA = ?,");
        sql.append("ST_ATIVO = ?");
        sql.append("WHERE ID_MODULO = ?");

        executarAlteracao(sql.toString(), criarParametros(entidade.getNoModulo(),
                entidade.getCdModulo(), entidade.getDsModulo(), entidade.getDsChamada(),
                entidade.getStAtivo(), entidade.getIdModulo()));
    }

    @Override
    public void excluir(ModuloVO entidade) {
        ConstrutorSQL sql = new ConstrutorSQL();

        sql.append("DELETE FROM TB_MODULO");
        sql.append("WHERE ID_MODULO = ?");

        executarAlteracao(sql.toString(), criarParametros(entidade.getIdModulo()));
    }

    @Override
    public ModuloVO consultarPorId(Serializable id) {
        ConstrutorSQL sql = new ConstrutorSQL();

        sql.append("SELECT * FROM TB_MODULO WHERE ID_MODULO = ?");

        return consultarUm(sql.toString(), criarParametros(id));
    }

    @Override
    public List<ModuloVO> consultarPorExemplo(ModuloVO exemplo) {
        List<ModuloVO> listaRetorno = null;

        ConstrutorSQL query = new ConstrutorSQL();

        query.append("SELECT * FROM TB_MODULO T WHERE 1=1");

        mapearQueryParaExemplo(query, exemplo);

        listaRetorno = consultar(query.toString(), recuperarParametros());

        return listaRetorno;
    }

    /**
     * Recupera um módulo a partir do seu nome.
     * 
     * @param noModulo Nome do módulo.
     * @return Objeto módulo.
     */
    public ModuloVO consultarUmPorNome(String noModulo) {
        ConstrutorSQL sql = new ConstrutorSQL();

        sql.append("SELECT * FROM TB_MODULO WHERE UPPER(NO_MODULO) = ?");

        return consultarUm(sql.toString(), criarParametros(noModulo.toUpperCase()));
    }

    /**
     * Recupera um módulo a partir do seu nome e do pai.
     * 
     * @param noModulo Nome do módulo.
     * @param cdModulo Id do pai.
     * @return Objeto módulo.
     */
    public ModuloVO consultarUmPorNomePorPai(String noModulo, Integer cdModulo) {
        ConstrutorSQL sql = new ConstrutorSQL();

        sql.append("SELECT * FROM TB_MODULO WHERE UPPER(NO_MODULO) = ? AND CD_MODULO = ?");

        return consultarUm(sql.toString(), criarParametros(noModulo.toUpperCase(), cdModulo));
    }

    /**
     * Recupera uma lista completa de módulos ordenada pelo nome
     * 
     * @return lista de módulos
     */
    public List<ModuloVO> consultarModulosOrdenadoPorNome() {
        ConstrutorSQL sql = new ConstrutorSQL();
        
        sql.append("SELECT *");
        sql.append("FROM TB_MODULO A");
//        sql.append("ORDER BY NO_MODULO ASC");
        
        return consultar(sql.toString());
    }

    /**
     * Recupera um módulo que tenha o mesmo nome passado,
     * porém id diferente.
     * 
     * @param idModulo Id do módulo.
     * @param noModulo Nome do módulo.
     * @return Objeto módulo.
     */
    public ModuloVO consultarUmPorIdDiferentePorNome(Integer idModulo, String noModulo) {
        ConstrutorSQL sql = new ConstrutorSQL();

        sql.append("SELECT * FROM TB_MODULO WHERE ID_MODULO <> ? AND UPPER(NO_MODULO) = ?");

        return consultarUm(sql.toString(), criarParametros(idModulo, noModulo));
    }

    /**
     * Recupera um módulo que tenha o mesmo nome passado,
     * porém id diferente.
     * 
     * @param idModulo Id do módulo.
     * @param noModulo Nome do módulo.
     * @param cdModulo Pai do módulo.
     * @return Objeto módulo.
     */
    public ModuloVO consultarUmPorIdDiferentePorNomePorPai(Integer idModulo, String noModulo, Integer cdModulo) {
        ConstrutorSQL sql = new ConstrutorSQL();

        sql.append("SELECT * FROM TB_MODULO WHERE ID_MODULO <> ? AND UPPER(NO_MODULO) = ? AND CD_MODULO = ?");

        return consultarUm(sql.toString(), criarParametros(idModulo, noModulo, cdModulo));
    }

    /**
     * Recupera uma lista de módulos filho que o usuário tem acesso
     * de acordo com o módulo pai passado.
     * 
     * @param idModuloPai Id do módulo pai.
     * @param idUsuario Id do usuário.
     * @return Lista de módulos.
     */
    public List<ModuloVO> consultarPorModuloPaiPorUsuario(Integer idModuloPai, Integer idUsuario) {
        ConstrutorSQL sql = new ConstrutorSQL();

        // Consulta os modulos pelo id do usuário, sendo que o usuário
        // pode ter modulo ao modulo pelo modulo que ele pertence.
        sql.append("SELECT *");
        sql.append("FROM TB_MODULO A,");
        sql.append("TB_ACESSO B,");
        sql.append("TB_PAPEL C");
        sql.append("WHERE C.CD_USUARIO = ?");
        sql.append("AND C.CD_GRUPO = B.CD_GRUPO");
        sql.append("AND B.CD_MODULO = A.ID_MODULO");
        sql.append("AND A.CD_MODULO = ?");
        sql.append("AND A.ST_ATIVO = 'S'");
        sql.append("ORDER BY A.DS_MODULO ASC");

        return consultar(sql.toString(), criarParametros(idUsuario, idModuloPai));
    }

    /**
     * Recupera uma lista ordenada de módulos que sejam filhos do
     * módulo pai passado.
     * 
     * @param idModuloPai Id do módulo pai.
     * @return Lista de módulos.
     */
    public List<ModuloVO> consultarPorModuloPaiOrdenadoPorNome(Integer idModuloPai) {
        ConstrutorSQL sql = new ConstrutorSQL();

        // Consulta os modulos pelo id do usuário, sendo que o usuário
        // pode ter modulo ao modulo pelo modulo que ele pertence.
        sql.append("SELECT *");
        sql.append("FROM TB_MODULO A");
        if (idModuloPai == null) {
            sql.append("WHERE A.CD_MODULO IS NULL");
        } else {
            sql.append("WHERE A.CD_MODULO = ?");
        }
        sql.append("ORDER BY A.NO_MODULO ASC");

        return consultar(sql.toString(), criarParametros(idModuloPai));
    }

    /**
     * Recupera uma lista ordenada de módulos que sejam filhos do
     * módulo pai passado.
     * 
     * @param idModuloPai Id do módulo pai.
     * @return Lista de módulos.
     */
    public List<ModuloVO> consultarPorModuloPaiOrdenadoPorId(Integer idModuloPai) {
        ConstrutorSQL sql = new ConstrutorSQL();

        // Consulta os modulos pelo id do usuário, sendo que o usuário
        // pode ter modulo ao modulo pelo modulo que ele pertence.
        sql.append("SELECT *");
        sql.append("FROM TB_MODULO A");
        if (idModuloPai == null) {
            sql.append("WHERE A.CD_MODULO IS NULL");
        } else {
            sql.append("WHERE A.CD_MODULO = ?");
        }
        sql.append("ORDER BY A.ID_MODULO ASC");
        
        if(idModuloPai == null) {
            return consultar(sql.toString());
        }

        return consultar(sql.toString(), criarParametros(idModuloPai));
    }

    @Override
    protected ModuloVO extrairObjetoResultado(ResultSet rs) throws SQLException {

        ModuloVO modulo = new ModuloVO();
        modulo.setIdModulo(rs.getInt("ID_MODULO"));
        modulo.setNoModulo(rs.getString("NO_MODULO"));
        modulo.setDsModulo(rs.getString("DS_MODULO"));
        modulo.setDsChamada(rs.getString("DS_CHAMADA"));
        modulo.setStAtivo(rs.getString("ST_ATIVO"));
        if(rs.getInt("CD_MODULO") == 0) {
            modulo.setCdModulo(null);
        } else {
            modulo.setCdModulo(new Integer(rs.getInt("CD_MODULO")));
        }

        return modulo;
    }

    @Override
    protected void mapearQueryParaExemplo(ConstrutorSQL query, ModuloVO exemplo) {

        if (exemplo.getNoModulo() != null && !exemplo.getNoModulo().isEmpty()) {
            query.append("AND T.NO_MODULO LIKE ?");
            adicionarParametro("%" + exemplo.getNoModulo() + "%");
        }

        if (exemplo.getDsModulo() != null && !exemplo.getDsModulo().isEmpty()) {
            query.append("AND T.DS_MODULO LIKE ?");
            adicionarParametro("%" + exemplo.getDsModulo() + "%");
        }

        if (exemplo.getDsChamada() != null && !exemplo.getDsChamada().isEmpty()) {
            query.append("AND T.DS_CHAMADA LIKE ?");
            adicionarParametro("%" + exemplo.getDsChamada() + "%");
        }

        if (exemplo.getStAtivo() != null && !exemplo.getStAtivo().isEmpty()) {
            query.append("AND T.ST_ATIVO = ?");
            adicionarParametro(exemplo.getStAtivo());
        }

        if (exemplo.getCdModulo() != null) {
            query.append("AND T.CD_MODULO = ?");
            adicionarParametro(exemplo.getCdModulo());
        }

    }
}
